<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>加密数据请求接口测试</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .container {
            background: white;
            border-radius: 10px;
            padding: 30px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            margin-bottom: 20px;
        }
        h1 {
            color: #333;
            text-align: center;
            margin-bottom: 30px;
        }
        h2 {
            color: #555;
            border-bottom: 2px solid #007bff;
            padding-bottom: 10px;
        }
        .form-group {
            margin-bottom: 20px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #555;
        }
        input, textarea, select {
            width: 100%;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
            font-size: 14px;
            box-sizing: border-box;
        }
        textarea {
            height: 100px;
            resize: vertical;
        }
        button {
            background-color: #007bff;
            color: white;
            padding: 12px 24px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
            margin-right: 10px;
            margin-bottom: 10px;
        }
        button:hover {
            background-color: #0056b3;
        }
        .success {
            background-color: #28a745;
        }
        .success:hover {
            background-color: #1e7e34;
        }
        .warning {
            background-color: #ffc107;
            color: #212529;
        }
        .warning:hover {
            background-color: #e0a800;
        }
        .result {
            background-color: #f8f9fa;
            border: 1px solid #dee2e6;
            border-radius: 5px;
            padding: 15px;
            margin-top: 20px;
            white-space: pre-wrap;
            font-family: 'Courier New', monospace;
            font-size: 12px;
            max-height: 300px;
            overflow-y: auto;
        }
        .error {
            background-color: #f8d7da;
            border-color: #f5c6cb;
            color: #721c24;
        }
        .success-result {
            background-color: #d4edda;
            border-color: #c3e6cb;
            color: #155724;
        }
        .info-box {
            background-color: #e7f3ff;
            border: 1px solid #b3d9ff;
            border-radius: 5px;
            padding: 15px;
            margin-bottom: 20px;
        }
        .two-column {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
        }
        @media (max-width: 768px) {
            .two-column {
                grid-template-columns: 1fr;
            }
        }
    </style>
</head>
<body>
    <h1>🔐 加密数据请求接口测试工具</h1>
    
    <div class="container">
        <div class="info-box">
            <h3>📋 测试说明</h3>
            <p><strong>AES密钥:</strong> aiServerAESKey16 (16位)</p>
            <p><strong>加密算法:</strong> AES/ECB/PKCS5Padding</p>
            <p><strong>支持的加密接口:</strong></p>
            <ul>
                <li>POST /api/auth/login - 用户登录（保护用户名和密码）</li>
                <li>POST /api/user/test-encrypt - 测试加密数据传输</li>
                <li>所有POST和PUT请求都支持加密</li>
            </ul>
            <p><strong>请求头:</strong> X-Encrypted: true</p>
            <p><strong>安全优势:</strong> 加密传输可以防止敏感数据（如密码）在网络传输过程中被窃听</p>
        </div>
    </div>

    <div class="two-column">
        <div class="container">
            <h2>🔧 配置设置</h2>
            <div class="form-group">
                <label for="serverUrl">服务器地址:</label>
                <input type="text" id="serverUrl" value="http://localhost:8080/api">
            </div>
            <div class="form-group">
                <label for="accessToken">访问令牌 (JWT):</label>
                <textarea id="accessToken" placeholder="请输入有效的JWT令牌"></textarea>
            </div>
            <div class="form-group">
                <label for="aesKey">AES密钥:</label>
                <input type="text" id="aesKey" value="aiServerAESKey16">
            </div>
        </div>

        <div class="container">
            <h2>📝 测试数据</h2>
            <div class="form-group">
                <label for="testData">要加密的测试数据:</label>
                <textarea id="testData" placeholder='{"message": "Hello World", "timestamp": 1234567890}'>{"message": "这是一条测试消息", "userId": 123, "action": "test"}</textarea>
            </div>
            <div class="form-group">
                <label for="encryptedData">加密后的数据:</label>
                <textarea id="encryptedData" readonly placeholder="点击'加密数据'按钮生成"></textarea>
            </div>
        </div>
    </div>

    <div class="container">
        <h2>🚀 操作面板</h2>
        <button onclick="encryptData()">🔒 加密数据</button>
        <button onclick="testEncryptedRequest()" class="success">📤 发送加密请求</button>
        <button onclick="testNormalRequest()" class="warning">📤 发送普通请求</button>
        <button onclick="testEncryptedLogin()" class="success">🔐 测试加密登录</button>
        <button onclick="testNormalLogin()" class="warning">🔓 测试普通登录</button>
        <button onclick="clearResults()">🗑️ 清空结果</button>
        
        <div id="result" class="result" style="display: none;"></div>
    </div>

    <div class="container">
        <h2>🔐 登录测试配置</h2>
        <div class="two-column">
            <div>
                <div class="form-group">
                    <label for="loginUsername">用户名:</label>
                    <input type="text" id="loginUsername" value="admin">
                </div>
                <div class="form-group">
                    <label for="loginPassword">密码:</label>
                    <input type="password" id="loginPassword" value="123456">
                </div>
            </div>
            <div>
                <div class="form-group">
                    <label for="encryptedLoginData">加密后的登录数据:</label>
                    <textarea id="encryptedLoginData" readonly placeholder="点击'测试加密登录'按钮生成"></textarea>
                </div>
            </div>
        </div>
    </div>

    <div class="container">
        <h2>📊 测试结果分析</h2>
        <div id="analysis" class="result" style="display: none;"></div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
    <script>
        // AES加密函数
        function aesEncrypt(text, key) {
            try {
                const keyUtf8 = CryptoJS.enc.Utf8.parse(key);
                const encrypted = CryptoJS.AES.encrypt(text, keyUtf8, {
                    mode: CryptoJS.mode.ECB,
                    padding: CryptoJS.pad.Pkcs7
                });
                return encrypted.toString();
            } catch (error) {
                console.error('加密失败:', error);
                return null;
            }
        }

        // AES解密函数
        function aesDecrypt(encryptedText, key) {
            try {
                const keyUtf8 = CryptoJS.enc.Utf8.parse(key);
                const decrypted = CryptoJS.AES.decrypt(encryptedText, keyUtf8, {
                    mode: CryptoJS.mode.ECB,
                    padding: CryptoJS.pad.Pkcs7
                });
                return decrypted.toString(CryptoJS.enc.Utf8);
            } catch (error) {
                console.error('解密失败:', error);
                return null;
            }
        }

        // 加密数据
        function encryptData() {
            const testData = document.getElementById('testData').value;
            const aesKey = document.getElementById('aesKey').value;
            
            if (!testData.trim()) {
                showResult('请输入要加密的测试数据', 'error');
                return;
            }
            
            if (!aesKey.trim()) {
                showResult('请输入AES密钥', 'error');
                return;
            }
            
            const encrypted = aesEncrypt(testData, aesKey);
            if (encrypted) {
                document.getElementById('encryptedData').value = encrypted;
                showResult('数据加密成功！\n原始数据: ' + testData + '\n加密后: ' + encrypted, 'success-result');
            } else {
                showResult('数据加密失败，请检查输入数据和密钥', 'error');
            }
        }

        // 解密响应函数
        async function decryptResponse(responseText) {
            try {
                const responseData = JSON.parse(responseText);
                if (responseData.encrypted && responseData.data) {
                    const aesKey = document.getElementById('aesKey').value;
                    const decrypted = aesDecrypt(responseData.data, aesKey);
                    return decrypted;
                }
                return null;
            } catch (error) {
                console.error('解密响应失败:', error);
                return null;
            }
        }

        // 发送加密请求
        async function testEncryptedRequest() {
            const serverUrl = document.getElementById('serverUrl').value;
            const accessToken = document.getElementById('accessToken').value;
            const encryptedData = document.getElementById('encryptedData').value;
            
            if (!encryptedData.trim()) {
                showResult('请先加密数据', 'error');
                return;
            }
            
            if (!accessToken.trim()) {
                showResult('请输入访问令牌', 'error');
                return;
            }
            
            try {
                const requestBody = {
                    data: encryptedData
                };
                
                const response = await fetch(`${serverUrl}/user/test-encrypt`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${accessToken}`,
                        'X-Encrypted': 'true'
                    },
                    body: JSON.stringify(requestBody)
                });
                
                const responseText = await response.text();
                let result = `🔐 加密请求测试结果\n`;
                result += `状态码: ${response.status}\n`;
                result += `响应头: ${JSON.stringify(Object.fromEntries(response.headers), null, 2)}\n`;
                result += `原始响应体: ${responseText}\n`;
                
                // 尝试解密响应
                const decryptedResponse = await decryptResponse(responseText);
                if (decryptedResponse) {
                    result += `\n🔓 解密后的响应体: ${decryptedResponse}\n`;
                }
                
                if (response.ok) {
                    showResult(result, 'success-result');
                    analyzeResponse(responseText, true, decryptedResponse);
                } else {
                    showResult(result, 'error');
                }
            } catch (error) {
                showResult(`请求失败: ${error.message}`, 'error');
            }
        }

        // 发送普通请求
        async function testNormalRequest() {
            const serverUrl = document.getElementById('serverUrl').value;
            const accessToken = document.getElementById('accessToken').value;
            const testData = document.getElementById('testData').value;
            
            if (!testData.trim()) {
                showResult('请输入测试数据', 'error');
                return;
            }
            
            if (!accessToken.trim()) {
                showResult('请输入访问令牌', 'error');
                return;
            }
            
            try {
                const response = await fetch(`${serverUrl}/user/test-encrypt`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${accessToken}`
                    },
                    body: testData
                });
                
                const responseText = await response.text();
                let result = `📤 普通请求测试结果\n`;
                result += `状态码: ${response.status}\n`;
                result += `响应头: ${JSON.stringify(Object.fromEntries(response.headers), null, 2)}\n`;
                result += `原始响应体: ${responseText}\n`;
                
                // 尝试解密响应
                const decryptedResponse = await decryptResponse(responseText);
                if (decryptedResponse) {
                    result += `\n🔓 解密后的响应体: ${decryptedResponse}\n`;
                }
                
                if (response.ok) {
                    showResult(result, 'success-result');
                    analyzeResponse(responseText, false, decryptedResponse);
                } else {
                    showResult(result, 'error');
                }
            } catch (error) {
                showResult(`请求失败: ${error.message}`, 'error');
            }
        }

        // 测试加密登录
        async function testEncryptedLogin() {
            const serverUrl = document.getElementById('serverUrl').value;
            const username = document.getElementById('loginUsername').value;
            const password = document.getElementById('loginPassword').value;
            const aesKey = document.getElementById('aesKey').value;
            
            if (!username.trim() || !password.trim()) {
                showResult('请输入用户名和密码', 'error');
                return;
            }
            
            try {
                // 构造登录数据
                const loginData = {
                    username: username,
                    password: password
                };
                
                const loginDataStr = JSON.stringify(loginData);
                
                // 加密登录数据
                const encrypted = aesEncrypt(loginDataStr, aesKey);
                if (!encrypted) {
                    showResult('登录数据加密失败', 'error');
                    return;
                }
                
                // 显示加密后的数据
                document.getElementById('encryptedLoginData').value = encrypted;
                
                const requestBody = {
                    data: encrypted
                };
                
                const response = await fetch(`${serverUrl}/auth/login`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-Encrypted': 'true'
                    },
                    body: JSON.stringify(requestBody)
                });
                
                const responseText = await response.text();
                let result = `🔐 加密登录测试结果\n`;
                result += `状态码: ${response.status}\n`;
                result += `响应头: ${JSON.stringify(Object.fromEntries(response.headers), null, 2)}\n`;
                result += `原始响应体: ${responseText}\n`;
                
                // 尝试解密响应
                const decryptedResponse = await decryptResponse(responseText);
                if (decryptedResponse) {
                    result += `\n🔓 解密后的响应体: ${decryptedResponse}\n`;
                }
                
                if (response.ok) {
                    showResult(result, 'success-result');
                    analyzeLoginResponse(responseText, true, decryptedResponse);
                    
                    // 如果登录成功，提取并保存JWT令牌
                    try {
                        let responseData;
                        if (decryptedResponse) {
                            responseData = JSON.parse(decryptedResponse);
                        } else {
                            responseData = JSON.parse(responseText);
                        }
                        
                        if (responseData.data && responseData.data.accessToken) {
                            document.getElementById('accessToken').value = responseData.data.accessToken;
                            showResult(result + '\n✅ JWT令牌已自动填入配置区域', 'success-result');
                        }
                    } catch (e) {
                        // 忽略JSON解析错误
                    }
                } else {
                    showResult(result, 'error');
                }
            } catch (error) {
                showResult(`加密登录请求失败: ${error.message}`, 'error');
            }
        }

        // 测试普通登录
        async function testNormalLogin() {
            const serverUrl = document.getElementById('serverUrl').value;
            const username = document.getElementById('loginUsername').value;
            const password = document.getElementById('loginPassword').value;
            
            if (!username.trim() || !password.trim()) {
                showResult('请输入用户名和密码', 'error');
                return;
            }
            
            try {
                const loginData = {
                    username: username,
                    password: password
                };
                
                const response = await fetch(`${serverUrl}/auth/login`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(loginData)
                });
                
                const responseText = await response.text();
                let result = `🔓 普通登录测试结果\n`;
                result += `状态码: ${response.status}\n`;
                result += `响应头: ${JSON.stringify(Object.fromEntries(response.headers), null, 2)}\n`;
                result += `原始响应体: ${responseText}\n`;
                
                // 尝试解密响应
                const decryptedResponse = await decryptResponse(responseText);
                if (decryptedResponse) {
                    result += `\n🔓 解密后的响应体: ${decryptedResponse}\n`;
                }
                
                if (response.ok) {
                    showResult(result, 'success-result');
                    analyzeLoginResponse(responseText, false, decryptedResponse);
                    
                    // 如果登录成功，提取并保存JWT令牌
                    try {
                        let responseData;
                        if (decryptedResponse) {
                            responseData = JSON.parse(decryptedResponse);
                        } else {
                            responseData = JSON.parse(responseText);
                        }
                        
                        if (responseData.data && responseData.data.accessToken) {
                            document.getElementById('accessToken').value = responseData.data.accessToken;
                            showResult(result + '\n✅ JWT令牌已自动填入配置区域', 'success-result');
                        }
                    } catch (e) {
                        // 忽略JSON解析错误
                    }
                } else {
                    showResult(result, 'error');
                }
            } catch (error) {
                showResult(`普通登录请求失败: ${error.message}`, 'error');
            }
        }

        // 分析登录响应
        function analyzeLoginResponse(responseText, isEncrypted, decryptedResponse = null) {
            let analysis = `📊 登录响应分析\n`;
            analysis += `请求类型: ${isEncrypted ? '加密登录' : '普通登录'}\n`;
            analysis += `响应时间: ${new Date().toLocaleString()}\n\n`;
            
            // 优先使用解密后的响应进行分析
            const analysisText = decryptedResponse || responseText;
            
            try {
                const responseData = JSON.parse(analysisText);
                analysis += `响应格式: JSON\n`;
                
                if (decryptedResponse) {
                    analysis += `🔓 响应已解密\n`;
                    analysis += `解密后的响应结构:\n${JSON.stringify(responseData, null, 2)}\n\n`;
                } else {
                    analysis += `响应结构:\n${JSON.stringify(responseData, null, 2)}\n\n`;
                }
                
                if (responseData.code !== undefined) {
                    analysis += `业务状态码: ${responseData.code}\n`;
                    if (responseData.code === 200) {
                        analysis += `✅ 登录成功\n`;
                    } else {
                        analysis += `❌ 登录失败\n`;
                    }
                }
                
                if (responseData.message) {
                    analysis += `响应消息: ${responseData.message}\n`;
                }
                
                if (responseData.data) {
                    analysis += `响应数据类型: ${typeof responseData.data}\n`;
                    
                    if (responseData.data.accessToken) {
                        analysis += `✅ 包含访问令牌 (长度: ${responseData.data.accessToken.length})\n`;
                    }
                    
                    if (responseData.data.refreshToken) {
                        analysis += `✅ 包含刷新令牌 (长度: ${responseData.data.refreshToken.length})\n`;
                    }
                    
                    if (responseData.data.user) {
                        analysis += `✅ 包含用户信息\n`;
                        analysis += `用户ID: ${responseData.data.user.id || 'N/A'}\n`;
                        analysis += `用户名: ${responseData.data.user.username || 'N/A'}\n`;
                    }
                }
                
                // 安全性分析
                analysis += `\n🔒 安全性分析:\n`;
                if (isEncrypted) {
                    analysis += `✅ 使用了加密传输，保护了用户凭据\n`;
                    if (decryptedResponse) {
                        analysis += `✅ 响应解密成功\n`;
                    } else {
                        analysis += `⚠️ 响应未加密或解密失败\n`;
                    }
                } else {
                    analysis += `⚠️ 未使用加密传输，用户凭据可能被窃听\n`;
                }
                
            } catch (error) {
                analysis += `响应格式: 非JSON格式\n`;
                analysis += `原始响应: ${responseText}\n`;
            }
            
            document.getElementById('analysis').textContent = analysis;
            document.getElementById('analysis').style.display = 'block';
        }
        function analyzeResponse(responseText, isEncrypted, decryptedResponse = null) {
            let analysis = `📊 响应分析\n`;
            analysis += `请求类型: ${isEncrypted ? '加密请求' : '普通请求'}\n`;
            analysis += `响应时间: ${new Date().toLocaleString()}\n\n`;
            
            try {
                const responseData = JSON.parse(responseText);
                analysis += `响应格式: JSON\n`;
                analysis += `响应结构:\n${JSON.stringify(responseData, null, 2)}\n\n`;
                
                if (responseData.code !== undefined) {
                    analysis += `业务状态码: ${responseData.code}\n`;
                }
                
                if (responseData.message) {
                    analysis += `响应消息: ${responseData.message}\n`;
                }
                
                if (responseData.data) {
                    analysis += `响应数据: ${responseData.data}\n`;
                }
                
                // 检查是否是加密响应
                if (responseData.encrypted) {
                    analysis += `🔒 响应已加密\n`;
                    if (decryptedResponse) {
                        analysis += `✅ 响应解密成功\n`;
                        analysis += `解密后的数据: ${decryptedResponse}\n`;
                    } else {
                        analysis += `❌ 响应解密失败\n`;
                    }
                } else {
                    // 检查是否包含解密数据的提示
                    if (responseData.data && responseData.data.includes('解密数据')) {
                        analysis += `✅ 服务器成功解密了请求数据\n`;
                    } else if (responseData.data && responseData.data.includes('普通数据')) {
                        analysis += `ℹ️ 服务器接收到普通（未加密）数据\n`;
                    }
                }
                
            } catch (error) {
                analysis += `响应格式: 非JSON格式\n`;
                analysis += `原始响应: ${responseText}\n`;
            }
            
            document.getElementById('analysis').textContent = analysis;
            document.getElementById('analysis').style.display = 'block';
        }

        // 显示结果
        function showResult(message, className = '') {
            const resultDiv = document.getElementById('result');
            resultDiv.textContent = message;
            resultDiv.className = 'result ' + className;
            resultDiv.style.display = 'block';
        }

        // 清空结果
        function clearResults() {
            document.getElementById('result').style.display = 'none';
            document.getElementById('analysis').style.display = 'none';
            document.getElementById('encryptedData').value = '';
            document.getElementById('encryptedLoginData').value = '';
        }

        // 页面加载时的初始化
        window.onload = function() {
            // 自动加密示例数据
            setTimeout(() => {
                encryptData();
            }, 500);
        };
    </script>
</body>
</html>